var email = require('emailjs');
var Db = require("../resources/database");
db = new Db();

var parser = require('cron-parser');
var cronSession = {}

function CronService() {
    
}

function event(type, msg, details){
    db.events.create( {
        msg: msg, details: details|'', type: type,
        source: { component: 'cron-service' }
    }, function(){});
}
//helper function for scripts
function sendEmail( to, subject, msg, cb){
    var cfg = require('../config.json').email;
    var server  = email.server.connect( cfg );
    server.send( {
        text: msg, from: cfg.from, to: to, subject: subject
      }, function (err, message) {
        if (err) {
          // handle error
          console.log('There was an error sending the email');
          console.log(err);
          event('error', 'sendEmail failed', err);
          if(cb)cb(err);
        }else {
            console.log('Email sended');
            console.log(message);
            event('info', 'sendEmail', message);
          if(cb)cb(null, message);
        }
      });
}
function scheduleActionExecuter( schedule, action, callback ){
    try { 
        //Evaluate action script and run it here
        if( action.enable )
            eval( action.script );
        callback();
        cronSession[ schedule.uuid ].timestamp = new Date();
    } catch (arguments) {
        // if evaluate exception occurs, catch it here
        console.log(arguments);
        event('fatal', 'action script '+action.name+'('+action.uuid+') failed', arguments);
        callback(arguments);
    }
}
function scheduleEvent( schedule ){
    //schedule Event hanlder
    console.log('scheduleEvent: '+schedule.name);
    
    //Event might contains several actions, so loop all actions here
    for( var i=0;i<schedule.actions.length;i++){
        db.actions.findOne( schedule.actions[i], function( err, action){
            if( err ){
                event('fatal', err);
            } else {
                // New action found and lets execute action
                scheduleActionExecuter(schedule, action, function(err, msg){
                    //what about then?
                });
            }
        });
    }
    // reinit schedule for next event
    initSchedule( schedule );
}

function initSchedule( schedule ){    
    if( schedule.enable ){
        //calculate cron string
        parser.parseExpression(schedule.cron, function(err, interval) {
            if( err ){
                event('fatal', err.message);
                console.log("Cron err:"+err);
            } else {
                //Calculate delay for next event from cron-parser interval
                delay = interval.next().getTime() - (new Date).getTime();
                console.log('Next event after ms:'+delay);
                timeoutId = setTimeout( function(){
                    //Cron event occurs, lets trig event
                    scheduleEvent( schedule );
                }, delay );
                cronSession[ schedule.uuid ].timeoutId = timeoutId;
            }
        });
    }
}

CronService.prototype.start = function(){
    db.schedules.find({}, function(err, schedules){
        if( err ) {
            event('fatal', err);
        } else {
            console.log("Init schedules: "+schedules.length);
            for(var i=0;i<schedules.length;i++){
                cronSession[ schedules[i].uuid ] = {
                    timeoutId: 0,
                    timestamp: new Date()
                }
                initSchedule( schedules[i] );
            };
        }
    });
}
CronService.prototype.stop = function(){
    for( var key in cronSession ){
        clearTimeout( cronSession[key].timeoutId );
    }
}
// export the class
module.exports = CronService;